<template>
    <div class="container">
        <button class="vnc" @click="renderVNC">Remote Device</button>
    </div>
</template>
<script>
// use axios send http request
import axios from '../../service/common-service/service';
export default {
    data() {
        return {
            /* The effect of JSESSIONID likes a access tonken to remote vnc */
            JSESSIONID: String
        };
    },
    /* All props is transmit from parent component */
    props: {
        thingName: String,
        tunnelName: String,
        vncPassword: Number,
        /* host is Thingworx address, for example https://192.168.70.67 */
        host: String,
        port: String,
        userName: String,
        passWord: String,
        cookieUrl: String
    },
    created() {
        this.getCookies();
    },
    methods: {
        _createVnc() {
            // open a new page，as vnc connection page
            var w = window.open("RemoteAccess", "#");
            var d = w.document.open();

            // set the cookies value，it was written to the cache when open the new page, it likes a access token
            var cookie = this.JSESSIONID;
            d.cookie = cookie;

            // the style of vnc connection page, it can be edit
            var styleBlock =
                '<style>' +
                    'body { margin: 0px; } ' +
                    '#noVNC_status_bar { width: 100%; } ' +
                    '#noVNC_status { position: relative; height: auto; } ' +
                    '#noVNC_buttons button { background: #01529a; border: 1px solid red; border-radius: 6px; display: inline; } ' +
                    '#noVNC_buttons button { margin: 0 3px; background: -webkit-linear-gradient(top, #349fd6 0%,#124ab5 100%); border: 1px solid #01529a; border-radius: 6px; } ' +
                    '#noVNC_buttons button:hover { background: -webkit-linear-gradient(top, #0060cc 0%,#013db6 100%); } ' +
                    '#noVNC_buttons button:active { background: #ccc; } ' +
                    '#noVNC_buttons button:disabled { opacity: 0.5; } ' +
                    '#noVNC_buttons button span { color: #ffffff }';
            styleBlock += '</style>';

            // JavaScript Library files path
            var libraryPath = '/static/websockettunnellibrary/';

            // JavaScript Librarys
            var scriptResources = '<script src="' + libraryPath + 'jquery-3.3.1.min.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'XSS.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'util.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'webutil.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'base64.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'websock.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'des.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'keysymdef.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'keyboard.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'input.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'display.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'rfb.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'keysym.js">' + "</scr" + "ipt>";
            scriptResources += '<script src="' + libraryPath + 'jsunzip.js">' + "</scr" + "ipt>";

            /* This script-init.js is most importent, all remote methods will be invoke at this file */
            scriptResources += '<script src="' + libraryPath + 'init.js">' + "</scr" + "ipt>";
            
            // This parameter is decided the tcp is 'wss' or 'ws', https=>wws | http=>ws
            var encryptConnection = (this.host.substring(0, 5) === "https");

            // These parameters are needed to connect VNC can be obtained in practical projects
            var remoteThing = {
                RemoteThingName: this.thingName,
                logLevel: 'warn',
                tunnelName: this.tunnelName,
                tunnelingUrl: 'Thingworx/WSTunnelClient',
                connectedThing: true,
                encryptConnection: encryptConnection,
                viewOnly: false,
                EnableStatusBarMessages: true,
                vncPassword: this.vncPassword,
                timeOut: 300000,
                tunnelId: this.tunnelId,
                host: this.host,
                port: this.port
            };

            // Initialize parameters by calling the _wstInit function of init.js
            var script = '<script>' +
                    '_wstInit({' +
                    ' thingName: "' + remoteThing.RemoteThingName + '",' +
                    ' connectedThing: ' + remoteThing.connectedThing + ',' +
                    ' logLevel: "' + remoteThing.logLevel + '",' +
                    ' encryptConnection: ' + remoteThing.encryptConnection + ',' +
                    ' viewOnly: ' + remoteThing.viewOnly + ',' +
                    ' vncPassword: "' + remoteThing.vncPassword + '",' +
                    ' tunnelingUrl: "' + remoteThing.tunnelingUrl + '",' +
                    ' tunnelName: "' + remoteThing.tunnelName + '",' +
                    ' timeOut: ' + remoteThing.timeOut + ',' +
                    ' showStatusMessages: ' + (remoteThing.EnableStatusBarMessages !== false) + ',' +
                    ' tunnelId: "' + remoteThing.tunnelId + '",' +
                    ' host: "' + remoteThing.host + '",' +
                    ' port: "' + remoteThing.port + '",' +
                    '});';
                script += "</scr" + "ipt>";

            // Stitching the body of a new page
            var body = '<body>' +
                    '<div id="noVNC_container">' +
                        '<div id="noVNC_status_bar" class="noVNC_status_bar">' +
                            '<table border=0 width="100%">' +
                                '<tr>' +
                                    '<td>' +
                                        '<div id="noVNC_buttons">' +
                                            '<button id="connectButton">' +
                                                '<span>' + "Connect" + '</span>' +  
                                            '</button>' +
                                            '<button id="sendCtrlAltDelButton">' +
                                                '<span>' + "CtrlAltDel" + '</span>' +  
                                            '</button>' +
                                            '<button id="shutdownButton">' +
                                                '<span>' + "Disconnect" + '</span>' + 
                                            '</button>' +
                                        '</div>' +
                                    '</td>' +
                                    '<td width="100%">' +
                                        '<div id="noVNC_status"></div>' +
                                    '</td>' +
                                '</tr>' +
                            '</table>' +
                        '</div>' +
                        '<div id="noVNC_inner_container">' +
                            '<div id="noVNC_canvas_wrapper">' +
                                '<canvas id="noVNC_canvas">Canvas not supported.</canvas>' +
                            '</div>' +
                        '</div>' +
                    '</div>' +
                '</body>';

            // Using the document.write() method to generate a completed HTML page
            d.write("<!DOCTYPE html>" +
                "<html>" +
                    "<head>" +
                        "<title>" + remoteThing.RemoteThingName + "</title>" +
                        "<meta charset=\"utf-8\">" +
                        "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">" +
                        "<link rel=\"stylesheet\" href=\"" + libraryPath + "base.css\" title=\"plain\">" +
                        scriptResources +
                        script +
                        styleBlock +
                    "</head>" +
                        body +
                "</html>");

            // page close method
            d.close();
        },
        renderVNC() {
            // You need a TunnelId to connect to vnc, which is acquired by this interface
            let time = new Date().getTime();
            let port;
            if (!this.host) {
                console.log('host is not exist!')
                return;
            }
            if (!this.port) {
                console.log('host is not exist!')
                return;
            }

            // Here '/api/' use proxy to handle the cross-domain, actually, it use host and port, as _url;
            let url = `/api/Thingworx/Subsystems/TunnelSubsystem/Services/StartTunnel?ts=${time}`;
            // let _url = `${this.host}:${port}/Thingworx/Subsystems/TunnelSubsystem/Services/StartTunnel?ts=${time}`;
            axios
            .post(url, {
                // The parameters required by the interface, three: things, timeout, tunnel
                thing: this.thingName, timeout: 300000, tunnel: this.tunnelName
            })
            .then(res => {
                if(res) {
                    try {
                        this.tunnelId = res.data.rows[0]['tunnelId'];
                        this._createVnc();
                    } catch(err) {
                        throw new Error('tunnelId is not exist!');
                    }
                }
            });
        },
        // Use getCookies() function to invoke the service 'GetCookies' to get the cookies of thingworx system
        getCookies() {
            let time = new Date().getTime();
            let url = `/api/Thingworx/Resources/ContentLoaderFunctions/Services/GetCookies?ts=${time}`;
            let param = {
                url: this.cookieUrl,
                username: this.userName,
                password: this.passWord
            }
            axios
            .post(url, param)
            .then(res => {
                if(res) {
                    try {
                        this.JSESSIONID = res.data.rows[0]['result'];
                    } catch(err) {
                        throw new Error('JSESSIONID is not exist!');
                    }
                }
            });
        }
    }
}
</script>
<style>
    .container .vnc {
        background: -webkit-linear-gradient(top, rgb(52, 159, 214) 0%, rgb(18, 74, 181) 100%);
        border-width: 1px;
        border-color: rgb(1, 82, 154);
        border-style: solid;
        border-radius: 6px;
        color: #ffffff;
        height: 25px;
        cursor: pointer;
        outline: none;
        font-size: 13px;
    }
</style>